/**
 * AI聊天面板主组件
 * 整合所有子组件，管理主要状态
 */
import React, { useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect } from 'react';
import {
  Box,
  Typography,
  TextField,
  IconButton,
  Divider,
  Chip,
  CircularProgress,
  Snackbar,
  Alert,
  useTheme,
  alpha,
  Tooltip,
  Button,
  Menu,
  MenuItem,
  ListItemIcon
} from '@mui/material';
import {
  Send as SendIcon,
  SmartToy as SmartToyIcon,
  Save as SaveIcon,
  History as HistoryIcon,
  Delete as DeleteIcon,
  RestartAlt as RestartAltIcon,
  MoreVert as MoreVertIcon
} from '@mui/icons-material';
import { generateAIResponse } from '../../utils/ai/generateAIResponse.ts';
import { intelligentCompressHistory } from '../../utils/ai/messageCompression.ts';
import { countTokensInMessages } from '../../utils/ai/tokenCounter.ts';
import { useNovel } from '../../context/NovelContext.tsx';
import { SelectedTextInfo, PolishType } from '../../types/text.ts';
import {
  Message,
  AIChatPanelProps,
  SnackbarState,
  SavedConversation,
  TokenLengthOption,
  DEFAULT_TOKEN_LENGTH,
  ChatMessage,
  TOKEN_LENGTH_VALUES
} from '../../types/chat.ts';
import { getPolishPromptTemplate, getEnhancedPolishPromptTemplate } from '../../utils/aiChat/polishPrompts.ts';
import { useStreamingMessage, useConversationStorage } from './hooks/index.ts';

// 直接导入各个组件
import SelectedTextPanel from './components/SelectedTextPanel.tsx';
import PolishOptionsBar from './components/PolishOptionsBar.tsx';
import SavedConversationsDialog from './components/SavedConversationsDialog.tsx';
import { MessageItem } from './components/MessageComponents.tsx';
import { MemoryStatusIndicator } from './components/MemoryStatusIndicator.tsx';

import {
  ChatContainer,
  ChatHeader,
  ChatContent,
  ChatInputArea,
  AIIcon,
  MessageActionButton,
  MessagesContainer,
  TypingDots
} from './styles/index.ts';

/**
 * AI聊天面板主组件
 */
const AIChatPanel: React.FC<AIChatPanelProps> = ({
  selectedText,
  selectionInfo,
  onApplyAISuggestion
}) => {
  const { currentItem } = useNovel();
  const theme = useTheme();
  const [messages, setMessages] = useState<Message[]>([]);
  const [historyMessages, setHistoryMessages] = useState<ChatMessage[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [inputText, setInputText] = useState('');
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const [snackbar, setSnackbar] = useState<SnackbarState>({
    open: false,
    message: '',
    severity: 'success'
  });
  const [hoveredMessageId, setHoveredMessageId] = useState<string | null>(null);
  const lastSelectedTextRef = useRef<string>('');
  const [selectedTextMessageId, setSelectedTextMessageId] = useState<string | null>(null);
  const [tokenLengthOption, setTokenLengthOption] = useState<TokenLengthOption>(() => {
    const savedOption = localStorage.getItem('preferred_token_length') as TokenLengthOption;
    return savedOption && Object.values(TokenLengthOption).includes(savedOption)
      ? savedOption
      : DEFAULT_TOKEN_LENGTH;
  });
  const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);
  const menuOpen = Boolean(menuAnchorEl);
  const [pinnedMessageIds, setPinnedMessageIds] = useState<Set<string>>(new Set());
  const [isSelectedTextExpanded, setIsSelectedTextExpanded] = useState<boolean>(true);

  // 使用自定义hooks
  const { isStreaming, streamingMessageId, handleStreamChunk, handleStreamChunkRef } = useStreamingMessage(setMessages);
  const {
    savedConversations,
    isDialogOpen,
    setIsDialogOpen,
    saveConversation,
    deleteConversation,
    openConversationsDialog
  } = useConversationStorage(currentItem?.name, setSnackbar);

  // 滚动到底部函数
  const scrollToBottom = useCallback(() => {
    setTimeout(() => {
      if (messagesEndRef.current) {
        messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
      }
    }, 100);
  }, [messagesEndRef]);

  // 处理token长度变更
  const handleTokenLengthChange = useCallback((option: TokenLengthOption) => {
    setTokenLengthOption(option);
    // 保存用户偏好到localStorage
    localStorage.setItem('preferred_token_length', option);
  }, []);

  // 处理已保存对话的加载
  const handleLoadConversation = useCallback((conversation: SavedConversation) => {
    setMessages(conversation.messages);
    setHistoryMessages(conversation.historyMessages);
    setIsDialogOpen(false);
    setSnackbar({
      open: true,
      message: '已加载对话记录',
      severity: 'success'
    });
  }, [setIsDialogOpen, setSnackbar]);

  // 重置对话
  const handleResetConversation = useCallback(() => {
    // 重置所有消息
    setMessages([]);
    setHistoryMessages([]);

    setSnackbar({
      open: true,
      message: '对话已重置',
      severity: 'success'
    });
  }, [setSnackbar]);

  // 为各种润色类型定义详细的提示词
  const getPolishPrompt = useCallback((polishType: PolishType, text: string): string => {
    return getPolishPromptTemplate(polishType, text);
  }, []);

  // 处理消息发送
  const handleSendMessage = async () => {
    if (!inputText.trim() || isLoading) return;

    // 先保存当前输入内容到临时变量
    const currentInputContent = inputText.trim();

    // 立即清空输入框
    setInputText('');

    // 创建用户消息
    const newMessage: Message = {
      id: `user-${Date.now().toString()}`,
      text: currentInputContent,
      isUser: true,
      timestamp: new Date(),
    };

    // 添加用户消息到UI
    setMessages(prev => [...prev, newMessage]);

    // 设置加载状态
    setIsLoading(true);

    try {
      // 压缩历史消息
      const compressedHistory = intelligentCompressHistory(
        historyMessages,
        TOKEN_LENGTH_VALUES[tokenLengthOption],
        [], // 没有固定消息
        15 // 保留最近15轮对话
      );

      // 创建新的聊天消息
      const newChatMessage: ChatMessage = {
        role: 'user',
        content: currentInputContent  // 使用保存的输入内容
      };

      // 更新历史消息
      setHistoryMessages(prev => [...prev, newChatMessage]);

      // 创建AI应答消息
      const aiMessageId = `ai-${Date.now().toString()}`;
      setMessages(prev => [...prev, {
        id: aiMessageId,
        text: '',
        isUser: false,
        timestamp: new Date(),
        isTypingIndicator: true,
        isNew: true
      }]);

      // 生成AI响应
      const response = await generateAIResponse(
        [...compressedHistory, newChatMessage],
        {
          maxTokens: TOKEN_LENGTH_VALUES[tokenLengthOption],
          temperature: 0.7,
          streamCallback: (chunk) => {
            if (chunk) {
              // 确保只处理有效内容，并传递chunk为独立单元
              handleStreamChunk(chunk, aiMessageId, false, false);
            }
          }
        }
      );

      if (response.success) {
        // 添加完整的AI消息到历史记录，但不再更新UI消息(已经在流式处理)
        const aiMessage: ChatMessage = {
            role: 'assistant',
          content: response.content || ''
        };

        // 最后一次更新，标记为结束
        handleStreamChunk("", aiMessageId, false, true);

        // 更新历史消息
        setHistoryMessages(prev => [...prev, aiMessage]);
        setIsLoading(false);
        scrollToBottom();
      } else {
        throw new Error(response.error || '生成响应失败');
      }

    } catch (error) {
      console.error('AI请求失败:', error);
      setIsLoading(false);

      setSnackbar({
        open: true,
        message: '请求失败，请检查网络连接',
        severity: 'error'
      });
    }
  };

  // 处理润色请求
  const handlePolishRequest = useCallback(async (polishType: PolishType) => {
    if (!selectedText || selectedText.trim().length === 0 || isLoading) return;

    // 获取针对此润色类型的详细提示词（使用增强版提示模板）
    const polishPrompt = getEnhancedPolishPromptTemplate(polishType, selectedText);
    console.log(`[润色请求] 类型: ${polishType}, 提示词长度: ${polishPrompt.length}`);

    // 设置加载状态
    setIsLoading(true);

    // 添加用户消息
    const userMessage: Message = {
      id: `user-${Date.now().toString()}`,
      text: polishPrompt,
      isUser: true,
      timestamp: new Date(),
    };

    // 添加新消息，不清空现有消息
    setMessages(prev => [...prev, userMessage]);

    try {
      // 压缩历史消息
      const compressedHistory = intelligentCompressHistory(
        historyMessages,
        TOKEN_LENGTH_VALUES[tokenLengthOption],
        [], // 没有固定消息
        15 // 保留最近15轮对话
      );

      // 创建新的聊天消息，保持一致的提示词
      const newChatMessage: ChatMessage = {
      role: 'user',
        content: polishPrompt
    };

    // 更新历史消息
      setHistoryMessages(prev => [...prev, newChatMessage]);

      // 创建全新的AI应答消息，确保ID不重复
      const aiMessageId = `ai-polish-${Date.now().toString()}`;
      console.log(`[润色请求] 创建新的AI消息: ${aiMessageId}`);

      setMessages(prev => [...prev, {
        id: aiMessageId,
        text: '',
        isUser: false,
        timestamp: new Date(),
        isTypingIndicator: true,
        isNew: true
      }]);

      // 生成AI响应
      const response = await generateAIResponse(
        [...compressedHistory, newChatMessage],
        {
          maxTokens: TOKEN_LENGTH_VALUES[tokenLengthOption],
          temperature: 0.7,
          streamCallback: (chunk) => {
            if (chunk) {
              // 确保只处理有效内容，并传递chunk为独立单元
              handleStreamChunk(chunk, aiMessageId, false, false);
            }
          }
        }
      );

      if (response.success) {
        // 添加完整的AI消息到历史记录，但不再更新UI消息(已经在流式处理)
        const aiMessage: ChatMessage = {
            role: 'assistant',
          content: response.content || ''
        };

        // 最后一次更新，标记为结束
        handleStreamChunk("", aiMessageId, false, true);

        // 更新历史消息
        setHistoryMessages(prev => [...prev, aiMessage]);
        setIsLoading(false);
        scrollToBottom();
      } else {
        throw new Error(response.error || '生成响应失败');
      }

    } catch (error) {
      console.error('处理润色请求失败:', error);
      setIsLoading(false);

      setSnackbar({
        open: true,
        message: '处理失败，请重试',
        severity: 'error'
      });
    }
  }, [selectedText, isLoading, getEnhancedPolishPromptTemplate, setMessages, messagesEndRef, setIsLoading, setSnackbar, historyMessages, tokenLengthOption, handleStreamChunk, scrollToBottom]);

  // 切换选中文本面板的展开/折叠状态
  const toggleSelectedTextPanel = useCallback(() => {
    setIsSelectedTextExpanded(prev => !prev);
  }, []);

  // 处理Snackbar关闭
  const handleCloseSnackbar = () => {
    setSnackbar(prev => ({ ...prev, open: false }));
  };

  // 添加选中文本变化监控
  useEffect(() => {
    console.log("AIChatPanel检测到selectedText变化:", selectedText);
    console.log("选中文本长度:", selectedText ? selectedText.length : 0);
    console.log("selectionInfo:", selectionInfo);

    if (selectedText && selectedText.trim().length > 0) {
      // 当有新选中文本时自动展开面板
      if (selectedText !== lastSelectedTextRef.current) {
        console.log("设置展开面板状态");
        setIsSelectedTextExpanded(true);
        lastSelectedTextRef.current = selectedText;

        // 生成唯一ID用于跟踪选中文本消息
        const newSelectedTextId = `selected-${Date.now().toString()}`;
        setSelectedTextMessageId(newSelectedTextId);
      }
    } else {
      // 没有选中文本时，确保状态清空
      console.log("清空选中文本状态");
      lastSelectedTextRef.current = '';
      setSelectedTextMessageId(null);
    }
  }, [selectedText, selectionInfo]);

  // 处理消息复制
  const handleCopyMessage = useCallback((messageId: string) => {
    const message = messages.find(msg => msg.id === messageId);
    if (message) {
      navigator.clipboard.writeText(message.text);
    setSnackbar({
      open: true,
      message: '已复制到剪贴板',
      severity: 'success'
    });
    }
  }, [messages, setSnackbar]);

  // 处理固定/取消固定消息
  const handleTogglePinMessage = useCallback((messageId: string) => {
    setPinnedMessageIds(prev => {
      const newPinnedIds = new Set(prev);
      if (newPinnedIds.has(messageId)) {
        newPinnedIds.delete(messageId);
      } else {
        newPinnedIds.add(messageId);
      }
      return newPinnedIds;
    });
  }, []);

  useEffect(() => {
    console.log('输入框内容更新:', inputText);
  }, [inputText]);

  // 监控消息更新
  useEffect(() => {
    if (messages.length > 0) {
      console.log('消息列表更新:', messages[messages.length - 1]);
    }
  }, [messages]);

  return (
    <ChatContainer>
      <ChatHeader>
        <Box sx={{ display: 'flex', alignItems: 'center' }}>
          <AIIcon>
            <SmartToyIcon style={{ fontSize: '0.9rem' }} />
          </AIIcon>
          <Typography variant="subtitle2" sx={{ fontWeight: 600, mr: 1 }}>AI助手</Typography>

          {/* 使用更小的灯型记忆状态指示器 */}
          <MemoryStatusIndicator
            currentTurns={messages.filter(m => m.isUser).length}
            maxTurns={20}
          />

          {/* 回复长度选择 - 更紧凑的设计 */}
          <Box
            sx={{
              display: 'flex',
              height: 24,
              border: 1,
              borderColor: 'divider',
              borderRadius: 1,
              overflow: 'hidden',
              ml: 1,
              fontSize: '0.7rem'  // 减小字体大小
            }}
          >
            {Object.values(TokenLengthOption).map((option, index) => (
              <React.Fragment key={option}>
                {index > 0 && (
                  <Divider orientation="vertical" flexItem sx={{ my: 0.25 }} />
                )}
                <Tooltip title={`设置回复长度: ${option}`}>
                  <Box
                    onClick={() => handleTokenLengthChange(option)}
                    sx={{
                      px: 0.75,  // 减少内边距
                      height: '100%',
              display: 'flex',
              alignItems: 'center',
                      fontSize: '0.7rem',
                      cursor: 'pointer',
                      bgcolor: tokenLengthOption === option ?
                        alpha(theme.palette.primary.main, 0.1) : 'transparent',
                      color: tokenLengthOption === option ? 'primary.main' : 'text.secondary',
                      '&:hover': {
                        bgcolor: alpha(theme.palette.primary.main, 0.05),
                      },
                      transition: 'all 0.2s'
                    }}
                  >
                    {option}
                  </Box>
                </Tooltip>
              </React.Fragment>
            ))}
          </Box>
        </Box>

        {/* 右侧操作按钮组 - 使用菜单合并不常用功能 */}
        <Box sx={{ display: 'flex', gap: 0.25 }}>
          {/* 保存对话按钮 */}
          <Tooltip title="保存当前对话">
            <IconButton
              size="small"
              onClick={() => saveConversation(messages, historyMessages)}
              disabled={messages.length === 0 || isLoading}
            >
              <SaveIcon sx={{ fontSize: '1rem' }} />
            </IconButton>
          </Tooltip>

          {/* 更多功能下拉菜单，合并次要功能 */}
          <Tooltip title="更多操作">
            <IconButton
              size="small"
              onClick={(e) => setMenuAnchorEl(e.currentTarget)}
              aria-expanded={menuOpen ? 'true' : undefined}
            >
              <MoreVertIcon sx={{ fontSize: '1rem' }} />
            </IconButton>
          </Tooltip>
          {/* 其他按钮可以移到菜单中 */}

          {/* 下拉菜单 */}
          <Menu
            anchorEl={menuAnchorEl}
            open={menuOpen}
            onClose={() => setMenuAnchorEl(null)}
            disableScrollLock
            PaperProps={{
              sx: { minWidth: '150px', mt: 0.5 }
            }}
          >
            <MenuItem
              onClick={() => {
                openConversationsDialog();
                setMenuAnchorEl(null);
              }}
              sx={{ fontSize: '0.8rem', py: 0.75 }}
            >
              <ListItemIcon>
                <HistoryIcon fontSize="small" />
              </ListItemIcon>
              查看历史对话
            </MenuItem>

            <MenuItem
              onClick={() => {
                handleResetConversation();
                setMenuAnchorEl(null);
              }}
            disabled={messages.length === 0 || isLoading}
              sx={{ fontSize: '0.8rem', py: 0.75 }}
          >
              <ListItemIcon>
            <RestartAltIcon fontSize="small" />
              </ListItemIcon>
              重置对话
            </MenuItem>

            <MenuItem
              onClick={() => {
                setMessages([]);
                setHistoryMessages([]);
                setSnackbar({
                  open: true,
                  message: '消息已清空',
                  severity: 'success'
                });
                setMenuAnchorEl(null);
              }}
              disabled={messages.length === 0 || isLoading}
              sx={{ fontSize: '0.8rem', py: 0.75 }}
            >
              <ListItemIcon>
                <DeleteIcon fontSize="small" />
              </ListItemIcon>
              清空消息
            </MenuItem>
          </Menu>

        </Box>
      </ChatHeader>

      {/* 主内容区 */}
      <Box sx={{
        flexGrow: 1,
        overflow: 'hidden',
        display: 'flex',
        flexDirection: 'column'
      }}>
        {/* 消息列表（可滚动） */}
        <Box sx={{ flexGrow: 1, overflow: 'auto' }}>
          {messages.length === 0 ? (
            <Box sx={{
              p: 2,  // 减少内边距
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'center',
              justifyContent: 'center',
              height: '100%',
              opacity: 0.7
            }}>
              <Typography
                variant="body2"
                color="text.secondary"
                sx={{ textAlign: 'center', mb: 1, fontSize: '0.85rem' }}  // 减小字体大小
              >
                开始新的对话，或从编辑器中选择文本
              </Typography>
              <Chip
                size="small"
                label="对话记录将保留最近20轮"
                sx={{ fontSize: '0.65rem', mt: 0.5, bgcolor: alpha(theme.palette.info.main, 0.1) }}  // 减小字体和间距
              />
            </Box>
          ) : (
            <MessagesContainer sx={{ p: 1.5, pb: 3 }}>  {/* 减少内边距 */}
          {messages.map((message) => (
                <MessageItem
                  key={message.id}
                  message={message}
                  onCopy={handleCopyMessage}
                  onTogglePin={handleTogglePinMessage}
                  pinnedMessageIds={pinnedMessageIds}
                  selectedTextInfo={selectionInfo}
                />
          ))}
          <div ref={messagesEndRef} />
        </MessagesContainer>
          )}
        </Box>

        {/* 底部固定区域 */}
        <Box sx={{ position: 'relative', flexShrink: 0 }}>
          {/* 选中文本面板（有条件显示） */}
          {typeof selectedText === 'string' && selectedText.trim().length > 0 ? (
            <Box sx={{
              position: 'relative',
              width: '100%',
              zIndex: 1,
              borderRadius: 1,
              mb: 0.5,
              boxShadow: '0 1px 3px rgba(0,0,0,0.05)'
            }}>
              <SelectedTextPanel
                text={selectedText}
                isExpanded={isSelectedTextExpanded}
                toggleExpanded={toggleSelectedTextPanel}
                locationInfo={selectionInfo?.sourceId || undefined}
                onCopyText={() => {
                  navigator.clipboard.writeText(selectedText);
                  setSnackbar({
                    open: true,
                    message: '已复制选中文本',
                    severity: 'success'
                  });
                }}
              />

              {/* 润色选项按钮组 - 优化对齐 */}
              <PolishOptionsBar
                selectedText={selectedText}
                selectionInfo={selectionInfo}
                onProcessRequest={handlePolishRequest}
            disabled={isLoading}
          />
            </Box>
          ) : (
            <Box sx={{ height: 0 }} />
        )}

          {/* 输入区域（始终可见） */}
          <ChatInputArea>
        {/* 输入框和按钮 */}
        <Box sx={{ display: 'flex', alignItems: 'center' }}>
          <TextField
            fullWidth
            variant="outlined"
            size="small"
            value={inputText}
                onChange={(e) => {
                  // 只有当是用户直接输入时才更新输入框内容
                  const newValue = e.target.value;
                  console.log('用户输入:', newValue);
                  setInputText(newValue);
                }}
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                if (inputText.trim() && !isLoading) {
                  handleSendMessage();
                }
              }
            }}
                // 使用key属性确保输入框始终为一个新实例，不受AI消息影响
                key="user-input-field"
                placeholder="请输入您的问题或指令..."
            multiline
            maxRows={8}
            disabled={isLoading}
            InputProps={{
              sx: {
                backgroundColor: theme.palette.mode === 'dark' ? alpha(theme.palette.background.paper, 0.3) : alpha(theme.palette.background.paper, 0.7),
                backdropFilter: 'blur(8px)',
                '&.Mui-focused': {
                  backgroundColor: theme.palette.mode === 'dark' ? alpha(theme.palette.background.paper, 0.5) : alpha(theme.palette.background.paper, 0.9),
                },
                    padding: '6px 10px',
                    '& .MuiInputBase-input': {
                      padding: '2px'
                    }
              }
            }}
          />
          <IconButton
            onClick={handleSendMessage}
            disabled={isLoading || !inputText.trim()}
                sx={{
                  ml: 0.5,
                  '& .MuiSvgIcon-root': {
                    fontSize: '1.2rem'
                  },
                  padding: '6px'
                }}
            color="primary"
          >
                {isLoading ? <CircularProgress size={20} /> : <SendIcon />}
          </IconButton>
        </Box>
      </ChatInputArea>
        </Box>
      </Box>

      <Snackbar
        open={snackbar.open}
        autoHideDuration={3000}
        onClose={handleCloseSnackbar}
        anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
      >
        <Alert
          onClose={handleCloseSnackbar}
          severity={snackbar.severity}
          variant="filled"
          sx={{ width: '100%' }}
        >
          {snackbar.message}
        </Alert>
      </Snackbar>

      {/* 已保存对话列表对话框 */}
      <SavedConversationsDialog
        open={isDialogOpen}
        onClose={() => setIsDialogOpen(false)}
        savedConversations={savedConversations}
        onLoadConversation={handleLoadConversation}
        onDeleteConversation={deleteConversation}
      />
    </ChatContainer>
  );
};

// 使用React.memo包装组件
export default React.memo(AIChatPanel); 
// 添加console.log以查看传入的props
// console.log("AIChatPanel props:", { selectedText, selectionInfo }); 